<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>透视投影继续-光照镜面反射有问题</title>
    <link rel="stylesheet" type="text/css" href="lib/webgl-tutorials.css">
   <style>
      body {
            margin: 0;
        }

        canvas {
            width: 100vw;
            height: 100vh;
            display: block;
        }
       p {
           font-size: smaller;
       }
    </style>
</head>
<body onload="main()">
    <canvas id="c" width="800" height="800"></canvas>
    <div style="position:fixed;top:10px;z-index: 99;left: 20px;color: #e2e2e2;font-family: Arial">
        <p >
            <div id="showfps" style="width: 70px;float: left"></div>
            <div id="showtime" style="width: 10px;float: left"></div>
        </p>
        <p id="showMouseXY"></p>
    </div>
    <div id="uiContainer">
        <div id="ui">
            <div id="u_ambientIntensity"></div>
            <div id="u_lightIntensity"></div>
            <div id="u_specularIntensity"></div>
            <div id="specularPowParam"></div>
        </div>
    </div>
</body>
<script type="notjs" id="vertext-shader-sc">
    attribute vec4 a_position;
    attribute vec4 a_normal;
    attribute vec4 a_color;
    uniform mat4 u_mvpMatrix;
    uniform mat4 u_normalMatrix;
    uniform mat4 u_selfWorldMatrix;//顶点世界矩阵
    uniform mat4 u_selfWorldViewMatrix;//观察空间和世界矩阵
    uniform vec3 u_lightPosition;//点光源位置

    varying vec4 v_normal;
    varying vec3 v_surfaceDirection;//世界坐标相对于光源的方向
    varying vec3 v_eyeDirection;//观察空间方向
    varying vec4 v_color;

    void main(){
        gl_Position = u_mvpMatrix * a_position;
        v_normal =  normalize(u_normalMatrix * a_normal);
        v_surfaceDirection = normalize(u_lightPosition - (u_selfWorldMatrix * a_position).xyz);
        v_eyeDirection = normalize((u_selfWorldViewMatrix * a_position).xyz);
        v_color = a_color;
    }
</script>
<script type="notjs" id="fragment-shader-sc">
    precision mediump float;

    varying vec4 v_color;
    varying vec4 v_normal;
    varying vec3 v_surfaceDirection;//世界坐标相对于光源的方向
    varying vec3 v_eyeDirection;//观察空间方向
    uniform vec3 u_lightColor;//光源颜色
    uniform vec3 u_ambientColor;//环境光颜色
    uniform float u_ambientIntensity;//环境光照强度
    uniform float u_lightIntensity;//点光源光照强度
    uniform float u_specularIntensity;//镜面反射强度
    uniform float u_specularPowParam;//光泽度

    void main(){
        vec3 normal = vec3(normalize(v_normal));
        //光照计算
        float dDot = max(dot(normalize(v_surfaceDirection), normal), 0.0);
        vec3 diffuse = u_lightIntensity * (u_lightColor * v_color.rgb * dDot);
        vec3 v_reflectionviewSurfaceDirection = reflect(-v_surfaceDirection, normal);//光线反射向量
        float spec = pow(max(dot(normalize(v_reflectionviewSurfaceDirection), v_eyeDirection), 0.0), u_specularPowParam);
        vec3 specular = u_specularIntensity * spec  * u_lightColor;
        vec3 ambient = u_ambientIntensity * (u_ambientColor * v_color.rgb);
        gl_FragColor = vec4(ambient + diffuse + specular, v_color.a);//
    }
</script>
<script type="notjs" id="sun-vertext-shader-sc">
    attribute vec4 a_position;
    uniform mat4 u_mvpMatrix;
    void main(){
        gl_Position = u_mvpMatrix * a_position;
    }
</script>
<script type="notjs" id="sun-fragment-shader-sc">
    precision mediump float;

    uniform vec4 u_color;

    void main(){
        gl_FragColor = u_color;
    }
</script>
<script type="text/javascript" src="lib/webgl-utils.js"></script>
<script type="text/javascript" src="lib/m4.js"></script>
<script type='text/javascript' src="lib/webgl-lessons-ui.js"></script>
<script type="text/javascript">
    var modelRotation = [0.0, 0.0, 0.0];

    var cameraTranslation = [0.0, 2.8, 7.5];
    var cameraTarget = [0.0, 0.0, -1.0];
    var cameraUp = [0.0, 1.0, 0.0];

    var lightTranslation = [0.0,2.0, 0.0];
    var lightColor = [1.0, 1.0, 1.0];
    var ambientColor = [0.2, 0.3, 0.3];
    var lightIntensity = 1.0;
    var specularIntensity = 1.0;
    var specularPowParam = 1.0;
    var ambientIntensity = 0.3;
    var cubeNum = 10;
    var randomTransltation = [];

    function main(){
        var cavans = document.getElementById("c");
        var gl = cavans.getContext("webgl");

        setupUI();

        var program = webglUtils.createProgramFromScripts(gl, ["vertext-shader-sc", "fragment-shader-sc"]);
        var a_position = gl.getAttribLocation(program, "a_position");
        var a_normal = gl.getAttribLocation(program, "a_normal");
        var u_normalMatrix = gl.getUniformLocation(program, "u_normalMatrix");
        var u_selfWorldMatrix = gl.getUniformLocation(program, "u_selfWorldMatrix");
        var u_selfWorldViewMatrix = gl.getUniformLocation(program, "u_selfWorldViewMatrix");
        var u_mvpMatrix = gl.getUniformLocation(program, "u_mvpMatrix");
        var u_lightPosition = gl.getUniformLocation(program, "u_lightPosition");
        var u_lightColor = gl.getUniformLocation(program, "u_lightColor");
        var u_ambientColor = gl.getUniformLocation(program, "u_ambientColor");
        var u_lightIntensity = gl.getUniformLocation(program, "u_lightIntensity");
        var u_ambientIntensity = gl.getUniformLocation(program, "u_ambientIntensity");
        var u_specularIntensity = gl.getUniformLocation(program, "u_specularIntensity");
        var u_specularPowParam = gl.getUniformLocation(program, "u_specularPowParam");
        var a_color = gl.getAttribLocation(program, "a_color");

        var sunProgram = webglUtils.createProgramFromScripts(gl, ["sun-vertext-shader-sc", "sun-fragment-shader-sc"]);
        var sun_position = gl.getAttribLocation(sunProgram, "a_position");
        var sun_color = gl.getUniformLocation(sunProgram, "u_color");
        var sun_mvpMatrix = gl.getUniformLocation(sunProgram, "u_mvpMatrix");

        var vertextBuffer = gl.createBuffer();
        var numVertex = setGeometry();

        var colorBuffer = gl.createBuffer();
        setColor();

        var normalBuffer = gl.createBuffer();
        setNormal();

        for(var i = 0;i < cubeNum; i++){
            randomTransltation.push([Math.random() * 100.0 - 50.0, Math.random() * 100.0 - 10.0, Math.random() * 100.0 - 100.0]);
        }

        setupEvent();

        var deltaTime = 0.0;
        var lastTimestamp = undefined;
        function anima(timestamp){
            return draw(timestamp);
        }

        function draw(timestamp){
            if(!lastTimestamp){
                lastTimestamp = timestamp;
            }
            deltaTime = timestamp - lastTimestamp;
            displayFPS(deltaTime);
            lastTimestamp = timestamp;
            webglUtils.resizeCanvasToDisplaySize(gl.canvas);
            gl.viewport(0, 0, gl.canvas.clientWidth, gl.canvas.clientHeight);
            gl.clearColor(0.1, 0.1, 0.1, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
            gl.enable(gl.DEPTH_TEST);
            gl.enable(gl.CULL_FACE);

            gl.useProgram(program);
            gl.enableVertexAttribArray(a_position);
            gl.bindBuffer(gl.ARRAY_BUFFER, vertextBuffer);
            gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(a_color);
            gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
            gl.vertexAttribPointer(a_color, 3, gl.UNSIGNED_BYTE, true, 0, 0);
            gl.enableVertexAttribArray(a_normal);
            gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
            gl.vertexAttribPointer(a_normal, 3, gl.FLOAT, true, 0, 0);

            //灯光
            gl.uniform3fv(u_lightPosition, lightTranslation);
            gl.uniform3fv(u_lightColor, lightColor);
            gl.uniform3fv(u_ambientColor, ambientColor);
            gl.uniform1f(u_lightIntensity, lightIntensity);
            gl.uniform1f(u_specularIntensity, specularIntensity);
            gl.uniform1f(u_ambientIntensity, ambientIntensity);
            gl.uniform1f(u_specularPowParam, specularPowParam);

            //var projectionMatrix = m4.orthographic(-1, 1, -1, 1, 1, -1);
            var projectionMatrix = m4.perspective(degToRad(60.0), gl.canvas.clientWidth / gl.canvas.clientHeight, 1, -20);
            var cameraMatrix = m4.lookAt(cameraTranslation,  m4.addVectors(cameraTranslation, cameraTarget), cameraUp);
            var viewMatrix = m4.inverse(cameraMatrix);

            var modelWorldMatrix = m4.translate(m4.identity(), 0, 0, 0);
            modelWorldMatrix = m4.scale(modelWorldMatrix, 5, 0.5, 2);
            modelWorldMatrix = m4.yRotate(modelWorldMatrix, degToRad(modelRotation[1]))
            var mvpMatrix = m4.multiply(projectionMatrix, viewMatrix);
            mvpMatrix = m4.multiply(mvpMatrix, modelWorldMatrix);
            gl.uniformMatrix4fv(u_mvpMatrix, false, mvpMatrix)

            var normalMatrix = m4.inverse(modelWorldMatrix);
            m4.transpose(normalMatrix, normalMatrix);
            gl.uniformMatrix4fv(u_normalMatrix, false, normalMatrix);
            gl.uniformMatrix4fv(u_selfWorldMatrix, false, modelWorldMatrix);
            gl.uniformMatrix4fv(u_selfWorldViewMatrix, false, m4.multiply(viewMatrix, modelWorldMatrix));

            gl.drawArrays(gl.TRIANGLES, 0 , numVertex);

            var angle = 10;
            for(var i = 0; i < cubeNum; i++){
                var modelWorldMatrixN = m4.translate(m4.identity(), randomTransltation[i][0], randomTransltation[i][1], randomTransltation[i][2]);
                modelWorldMatrixN = m4.yRotate(modelWorldMatrixN, degToRad(angle += angle))
                var mvpMatrixN = m4.multiply(projectionMatrix, viewMatrix);
                mvpMatrixN = m4.multiply(mvpMatrixN, modelWorldMatrixN);
                gl.uniformMatrix4fv(u_mvpMatrix, false, mvpMatrixN);

                var normalMatrixN = m4.inverse(modelWorldMatrixN);
                m4.transpose(normalMatrixN, normalMatrixN);
                gl.uniformMatrix4fv(u_normalMatrix, false, normalMatrixN);
                gl.uniformMatrix4fv(u_selfWorldMatrix, false, modelWorldMatrixN);
                gl.uniformMatrix4fv(u_selfWorldViewMatrix, false, m4.multiply(viewMatrix, modelWorldMatrixN));

                gl.drawArrays(gl.TRIANGLES, 0 , numVertex);
            }

            //绘制一圈
            var angle = 0.0;
            for(var i = 0; i < cubeNum; i++){
                var modelWorldMatrixN = m4.translate(m4.identity(), Math.cos(degToRad(angle)) * 4.0, Math.sin(degToRad(angle))  * 4.0, -7.0);
                modelWorldMatrixN = m4.translate(modelWorldMatrixN, 0.0, 5.0, 0.0);
                modelWorldMatrixN = m4.scale(modelWorldMatrixN, 1, 1, 1);
                var mvpMatrixN = m4.multiply(projectionMatrix, viewMatrix);
                mvpMatrixN = m4.multiply(mvpMatrixN, modelWorldMatrixN);
                gl.uniformMatrix4fv(u_mvpMatrix, false, mvpMatrixN);

                var normalMatrixN = m4.inverse(modelWorldMatrixN);
                m4.transpose(normalMatrixN, normalMatrixN);
                gl.uniformMatrix4fv(u_normalMatrix, false, normalMatrixN);
                gl.uniformMatrix4fv(u_selfWorldMatrix, false, modelWorldMatrixN);
                gl.uniformMatrix4fv(u_selfWorldViewMatrix, false, m4.multiply(viewMatrix, modelWorldMatrixN));

                //额外添加镜面反射强度测试
                gl.uniform1f(u_specularIntensity, specularIntensity * i * 0.1 + specularIntensity);

                angle += 360.0 / cubeNum;
                gl.drawArrays(gl.TRIANGLES, 0 , numVertex);
            }

            //绘制灯
            gl.useProgram(sunProgram);
            gl.enableVertexAttribArray(sun_position);
            gl.bindBuffer(gl.ARRAY_BUFFER, vertextBuffer);
            gl.vertexAttribPointer(sun_position, 3, gl.FLOAT, false, 0, 0);
            var modelWorldMatrix2 = m4.translate(m4.identity(), lightTranslation[0], lightTranslation[1], lightTranslation[2]);
            modelWorldMatrix2 = m4.scale(modelWorldMatrix2, 0.2, 0.2, 0.2);
            var mvpMatrix2 = m4.multiply(projectionMatrix, viewMatrix);
            mvpMatrix2 = m4.multiply(mvpMatrix2, modelWorldMatrix2);
            gl.uniformMatrix4fv(sun_mvpMatrix, false, mvpMatrix2);
            gl.uniform4f(sun_color, lightColor[0], lightColor[1], lightColor[2], 1.0);

            gl.drawArrays(gl.TRIANGLES, 0 , numVertex);

            requestAnimationFrame(draw);
        }

        requestAnimationFrame(anima);

        var lastShowTime = 0;
        function displayFPS(deltaTime){
            if(deltaTime < 2.0 || lastShowTime < 50){
                lastShowTime += deltaTime;
                return;
            }
            //FPS
            var fps = Math.floor(1000.0 / deltaTime);
            document.getElementById("showfps").innerText  = "FPS:" + fps;
            document.getElementById("showtime").innerText  = Math.round(deltaTime) + "ms";
            lastShowTime = 0;
        }

        function setGeometry(){
            //    v6----- v5
            //   /|      /|
            //  v1------v0|
            //  | |     | |
            //  | |v7---|-|v4
            //  |/      |/
            //  v2------v3
            var positions = [
                // v0-v1-v2-v3 front
                0.5, 0.5, 0.5,//0
                -0.5,0.5,0.5,//1
                -0.5,-0.5,0.5,//2
                0.5,0.5,0.5,//0
                -0.5,-0.5,0.5,//2
                0.5,-0.5,0.5,//3

                // v0-v3-v4-v5 right
                0.5, 0.5, 0.5,//0
                0.5,-0.5,0.5,//3
                0.5, -0.5, -0.5,//4
                0.5, 0.5, 0.5,//0
                0.5,-0.5,-0.5,//4
                0.5,0.5,-0.5,//5

                // v0-v5-v6-v1 up
                0.5, 0.5, 0.5,//0
                0.5,0.5,-0.5,//5
                -0.5,0.5,-0.5,//6
                0.5, 0.5, 0.5,//0
                -0.5,0.5,-0.5,//6
                -0.5,0.5,0.5,//1

                // v1-v6-v7-v2 left
                -0.5, 0.5, 0.5,//1
                -0.5, 0.5, -0.5,//6
                -0.5,-0.5, -0.5,//7
                -0.5, 0.5, 0.5,//1
                -0.5,-0.5, -0.5,//7
                -0.5,-0.5,0.5,//2

                // v7-v4-v3-v2 bottom
                -0.5,-0.5,-0.5,//7
                0.5,-0.5,-0.5,//4
                0.5,-0.5,0.5,//3
                -0.5,-0.5,-0.5,//7
                0.5,-0.5,0.5,//3
                -0.5,-0.5,0.5,//2

                // v4-v7-v6-v5 back
                0.5,-0.5,-0.5,//4
                -0.5,-0.5,-0.5,//7
                -0.5, 0.5, -0.5,//6
                0.5,-0.5,-0.5,//4
                -0.5, 0.5, -0.5,//6
                0.5,0.5,-0.5,//5
            ];
            gl.bindBuffer(gl.ARRAY_BUFFER, vertextBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
            return positions.length / 3;
        }

        function setColor(){
            var colors = [
                // front
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,


                // right
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,

                // top
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,

                //left
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,

                //bottom
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,

                //back
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
                95, 158, 160,
            ];

            gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(colors), gl.STATIC_DRAW);
        }

        function setNormal(){
            var normals = [
                // v0-v1-v2-v3 front
                0, 0, 1,//0
                0, 0, 1,//1
                0, 0, 1,//2
                0, 0, 1,//0
                0, 0, 1,//2
                0, 0, 1,//3

                // v0-v3-v4-v5 right
                1, 0, 0,//0
                1, 0, 0,//5
                1, 0, 0,//6
                1, 0, 0,//0
                1, 0, 0,//6
                1, 0, 0,//1

                // v0-v5-v6-v1 up
                0, 1, 0,//0
                0, 1, 0,//3
                0, 1, 0,//4
                0, 1, 0,//0
                0, 1, 0,//4
                0, 1, 0,//5

                // v1-v6-v7-v2 left
                -1, 0, 0,//7
                -1, 0, 0,//4
                -1, 0, 0,//3
                -1, 0, 0,//7
                -1, 0, 0,//3
                -1, 0, 0,//2

                // v7-v4-v3-v2 bottom
                0, -1, 0,//1
                0, -1, 0,//6
                0, -1, 0,//7
                0, -1, 0,//1
                0, -1, 0,//7
                0, -1, 0,//2

                // v4-v7-v6-v5 back
                0, 0, -1,//4
                0, 0, -1,//7
                0, 0, -1,//6
                0, 0, -1,//4
                0, 0, -1,//6
                0, 0, -1,//5
            ];
            gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
        }

        function setupEvent(){
            document.addEventListener("keydown", onkeyEvent);
            cavans.addEventListener("mousedown", onMouseEvent('in'));
            cavans.addEventListener("mousemove", onMouseEvent('move'));
            cavans.addEventListener("mouseup", onMouseEvent('out'));
            cavans.addEventListener("mouseout", onMouseEvent('out'));
        }

        function onkeyEvent(ev){
            switch (ev.keyCode) {
                case 87:
                    moveForward(0.1);
                    break;
                case 83:
                    moveForward(-0.1);
                    break;
                case 65:
                    moveRight(-0.1);
                    break;
                case 68:
                    moveRight(0.1);
                    break;
                case 81:
                    moveUp(0.1);
                    break;
                case 69:
                    moveUp(-0.1);
                    break;
                case 90:
                    turn(0.1);
                    break;
                case 88:
                    turn(-0.1);
                    break;
                default:
                    return;
            }
        }

        function moveForward(val){
            cameraTranslation = m4.addVectors(cameraTranslation, vecMuliNum(cameraTarget, val));
            //console.log(cameraTranslation)
        }

        function moveUp(val){
            cameraTranslation = m4.addVectors(cameraTranslation, vecMuliNum(cameraUp, val));
            //console.log(cameraTranslation)
        }

        function moveRight(val){
            //根据 target 和 up 叉积出出 x 向量; 标准化，只需要方向
            var xVector = m4.cross(m4.normalize(cameraTarget), m4.normalize(cameraUp));
            cameraTranslation = m4.addVectors(cameraTranslation, vecMuliNum(xVector, val));
            //console.log(cameraTranslation);
        }

        function turn(val){
            modelRotation[1] += val * 10;
        }

        var lastMouseXY = [];
        var pitch = 0.0;
        var yaw = 90.0;
        var mouseFirstInCanvas = false;

        function onMouseEvent(type){
            switch (type) {
                case 'in':
                    return function (ev){
                        //console.log("start.")
                        //鼠标距离最左边
                        var mX = ev.clientX;
                        var mY = ev.clientY;
                        lastMouseXY[0] = mX;
                        lastMouseXY[1] = mY;
                        mouseFirstInCanvas = true;
                    }
                    break;
                case 'move':
                    return function (ev){
                        if(!mouseFirstInCanvas){
                            return false;
                        }
                        //鼠标距离最左边
                        var mX = ev.clientX;
                        var mY = ev.clientY;

                        //x方向偏移量
                        var xOffset = mX - lastMouseXY[0];
                        var yOffset = mY - lastMouseXY[1];

                        //console.log(xOffset + "," + yOffset);
                        //document.getElementById("showMouseXY").innerText = "当前鼠标坐标：" + mX + "," + mY;

                        // yaw 围绕 y轴， 偏航角
                        // pitch 围绕x轴，俯仰角
                        // roll 围绕z轴，翻滚角
                        pitch += yOffset * 0.1;
                        yaw += xOffset * 0.1;
                        /*if(pitch >= 90.0){
                            pitch = 90.0;
                        }
                        if(pitch <= -90.0){
                            pitch = -90.0;
                        }*/
                        cameraTarget[0] = Math.cos(degToRad(yaw)) * Math.cos(degToRad(pitch));
                        cameraTarget[1] = Math.sin(degToRad(pitch));

                        lastMouseXY[0] = mX;
                        lastMouseXY[1] = mY;
                    }
                    break;
                case 'out':
                    return function (ev){
                        //console.log("end.")
                        //鼠标距离最左边
                        var mX = ev.clientX;
                        var mY = ev.clientY;
                        lastMouseXY[0] = mX;
                        lastMouseXY[1] = mY;
                        mouseFirstInCanvas = false;
                    }
                    break;
                default:
                    return;
            }
        }


        function setupUI(){
            webglUtils.resizeCanvasToDisplaySize(gl.canvas);
            webglLessonsUI.setupSlider("#u_ambientIntensity", {value: ambientIntensity * 10.0, slide: updateAmbientIntensity, min: 0.0, max:10 ,step:0.01});
            webglLessonsUI.setupSlider("#u_lightIntensity", {value: lightIntensity * 10.0, slide: updateLightIntensity, min: 0.0, max:10 ,step:0.01});
            webglLessonsUI.setupSlider("#u_specularIntensity", {value: specularIntensity * 10.0, slide: updateSpecularIntensity, min: 0.0, max:10 ,step:0.01});
            webglLessonsUI.setupSlider("#specularPowParam", {value: specularPowParam * 10.0, slide: updateSpecularPowParam, min: 0.0, max:20 ,step:1});
        }

        function updateAmbientIntensity(ev, ui){
            ambientIntensity = ui.value / 10.0;
        }

        function updateLightIntensity(ev, ui){
            lightIntensity = ui.value / 10.0;
        }

        function updateSpecularIntensity(ev, ui){
            specularIntensity = ui.value / 10.0;
        }

        function updateSpecularPowParam(ev, ui){
            specularPowParam = ui.value / 10.0;
        }
    }

    function degToRad(d){
        return d * Math.PI / 180;
    }

    function radToDeg(r) {
        return r * 180 / Math.PI;
    }

    /**
     * 向量 * 标量
     * @param v1
     * @param num
     * @returns {*[]}
     * @constructor
     */
    function vecMuliNum(v1, num){
        var res = [];
        for(var i = 0; i < v1.length; i++){
            res[i] = v1[i] * num;
        }
        return res;
    }
</script>
</html>














